﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Configuration;
using SimpleModel.Env;

namespace SimpleModel.Context
{
    public class MDBContext:DbContext,IRepository
    {
        private static string connectionString = !string.IsNullOrEmpty(DBConfig.connectionConfig)&&
            ConfigurationManager.ConnectionStrings[DBConfig.connectionConfig] != null?
            ConfigurationManager.ConnectionStrings[DBConfig.connectionConfig].ConnectionString:
            DBConfig.defaultConnectionString ;
        public MDBContext() : this(connectionString)
        {
            
        }
        public MDBContext(string connectString):base(connectString)
        {
            
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            Type ttype = typeof (MDBContext);
            var typesToRegister = ttype.Assembly.GetTypes().
                Where(type => !String.IsNullOrEmpty(type.Namespace)).
                Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = Activator.CreateInstance(type);
                modelBuilder.Configurations.Add(configurationInstance);
            }
            base.OnModelCreating(modelBuilder);
        }
        int IRepository.ACount<TEntityType>()
        {
            return this.ACount<TEntityType>();
        }

        IQueryable<TEntityType> IRepository.GetAll<TEntityType>()
        {
            return this.GetAll<TEntityType>();
        }

        TEntityType IRepository.FindOne<TEntityType>(params object[] keyValues)
        {
            return this.FindOne<TEntityType>(keyValues);
        }

        IQueryable<TEntityType> IRepository.FindByQuery<TEntityType>(Expression<Func<TEntityType, bool>> expressio)
        {
            return this.FindByQuery(expressio);
        }


        IQueryable<TEntityType> IRepository.Search<TEntityType>(Expression<Func<TEntityType, bool>> expression, bool asc,
            Expression<Func<TEntityType, object>> keySelector, int pageIndex, int pageSize, ref int total)
        {
            return this.Search(expression, asc, keySelector, pageIndex, pageSize, ref total);
        }

        IQueryable<TEntityType> IRepository.Search<TEntityType>(Expression<Func<TEntityType, bool>> expression, string orderString,
            int pageIndex, int pageSize, ref int total)
        {
            return this.Search(expression, orderString, pageIndex, pageSize, ref total);
        }

        void IRepository.AddOne<TEntityType>(TEntityType entity)
        {
            this.AddOne(entity);
        }

        void IRepository.AddMultiple<TEntityType>(List<TEntityType> entityList)
        {
            this.AddMultiple(entityList);
        }

        void IRepository.UpdateOne<TEntityType>(TEntityType entity)
        {
            this.UpdateOne(entity);
        }

        void IRepository.DeleteOne<TEntityType>(TEntityType entity)
        {
            this.DeleteOne(entity);
        }

        void IRepository.DeleteMultiple<TEntityType>(Expression<Func<TEntityType, bool>> expression)
        {
            this.DeleteMultiple<TEntityType>(expression);
        }

        bool IRepository.AddOneAndSave<TEntityType>(TEntityType entity)
        {
            return this.AddOneAndSave(entity);
        }

        bool IRepository.AddMultipleAndSave<TEntityType>(List<TEntityType> entityList)
        {
            return this.AddMultipleAndSave(entityList);
        }

        bool IRepository.UpdateOneAndSave<TEntityType>(TEntityType entity)
        {
            return this.UpdateOneAndSave(entity);
        }
        bool IRepository.UpdateOneAndSave<TEntityType>(TEntityType entity, bool updateAll, params string[] propertyNames)
        {
            return this.UpdateOneAndSave(entity, updateAll, propertyNames);
        }

        bool IRepository.DeleteOneAndSave<TEntityType>(TEntityType entity)
        {
            return this.DeleteOneAndSave(entity);
        }

        bool IRepository.Save()
        {
            return this.Save();
        }

        int IRepository.UpdateMultipleAndSave<TEntityType>(Expression<Func<TEntityType, bool>> queryExpression,
            Expression<Func<TEntityType, TEntityType>> updateExpression)
        {
            return this.UpdateMultipleAndSave(queryExpression, updateExpression);
        }

        int IRepository.DeleteMultipleAndSave<TEntityType>(Expression<Func<TEntityType, bool>> expression)
        {
            return this.DeleteMultipleAndSave(expression);
        }
    }
}
